<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    "use strict";

    // ES5  => ES5严格模式 =>  ES6


    // ES5严格模式
    // JS在发展历程中的一次尝试,让JS语法更加严格,规范, 解决ES5在语法中存在的 不合理 不严谨 不安全的地方,为未来的版本发展作准备

    // 如何进入严格模式?
    // 在作用域的最前面添加关键词 "use strict";
    // 全局作用域  => 在当前script脚本的最前面添加关键词 "use strict";
    // 函数作用域  => 在函数上下文的最前面添加关键词 "use strict";

    /* function fn() {
        "use strict";
        var a = 10;
        b = 20;
        console.log(a, b)
    }
    fn(); */

    // 1. 严格模式中,不通过关键词var直接声明的变量 会报错
    // var a = 10;
    // b = 20;
    // console.log(a, b)

    // 2. 严格模式中,重复声明多个参数会报错 =>  Duplicate parameter name not allowed in this context
    // function add(a, b, b) {
    //     return a + b;
    // }
    // var result = add(1, 2, 3);
    // console.log(result);

    // 3. 严格模式中 => 禁止this指向window (要求函数调用时要有依存的对象 如果没有依存的对象 this -> undefined)

    /* function fn() {
        console.log(this);
    }
    // fn();
    window.fn();

    (function () {
        console.log(this);
    })() */

    // 4. 严格模式中 新增eval作用域  => 在eval中声明的变量也是局部的
    // eval("var x = 10; var y = 20; var z = x + y; console.log(x,y,z)");
    // console.log("eval之后:", x, y, z);

    // 5. 严格模式中 如果某个对象的属性禁止删除  直接删除会报错

    // var zhang = {};
    // Object.defineProperties(zhang, {
    //     name: {
    //         value: "张三",
    //         writable: false,
    //         enumerable: false,
    //         configurable: true,
    //     },
    //     age: {
    //         value: 25,
    //         writable: false,
    //         enumerable: false,
    //         configurable: false,
    //     },
    //     height: {
    //         value: "175cm",
    //         writable: false,
    //         enumerable: false,
    //         configurable: false,
    //     },
    //     weight: {
    //         value: "70kg",
    //         writable: false,
    //         enumerable: false,
    //         configurable: false,
    //     }
    // })

    // console.log(delete zhang.name);
    // console.log(delete zhang.age);

    // 全局的变量和方法都存在window中  => window.m window.n
    // window中定义的 自定义的变量和方法不能被删除 => 严格模式中删除会报错
    var m = 10;
    var n = 20;

    console.log(Object.getOwnPropertyDescriptor(window, "m"));
    console.log(Object.getOwnPropertyDescriptor(window, "n"));

    console.log(Object.getOwnPropertyDescriptors(window));



</script>

</html>